//语法甘露：
var object = // 定义小写的object基本类，用于实现最基础的方法等
{
	isA : function(aType) // 一个判断类与类之间以及对象与类之间关系的基础方法
	{
		var self = this;
		while (self) {
			if (self == aType)
				return true;
			self = self.Type;
		};
		return false;
	}
};

function Class(aBaseClass, aClassDefine) // 创建类的函数，用于声明类及继承关系
{
	function class_() // 创建类的临时函数壳
	{
		this.Type = aBaseClass; // 我们给每一个类约定一个Type属性，引用其继承的类
		for (var member in aClassDefine)
			this[member] = aClassDefine[member]; // 复制类的全部定义到当前创建的类
	};
	class_.prototype = aBaseClass;
	return new class_();
};

function New(aClass, aParams) // 创建对象的函数，用于任意类的对象创建
{
	function new_() // 创建对象的临时函数壳
	{
		this.Type = aClass; // 我们也给每一个对象约定一个Type属性，据此可以访问到对象所属的类
		if (aClass.Create)
			aClass.Create.apply(this, aParams); // 我们约定所有类的构造函数都叫Create，这和DELPHI比较相似
	};
	new_.prototype = aClass;
	return new new_();
};

var WSClient = Class(object, {
	Create:function(url,con_span,scns,cn_ids,fids){
		this.url = url;
		this.data = {};
		//自动重连间隔,-1不重连
		this.con_span=con_span||10000;
		this.func_state={};
		this.func_evt={};
		//已订阅状态
		this.scns=scns;
		this.cn_ids=cn_ids;
		this.fids=fids;
		this.logpr={};
		//this.connect();
	},
	setevt:function(sn,func){
		this.func_evt[sn]=func;
	},
	setfunc:function(sn,func){
		this.func_state[sn]=func;
	},
	getStateByCn:function(cn){
		return this.data[cn];
	},
	getState:function(cn,key){
		var smap = this.data[cn];
		if(smap){
			return smap[key];
		}
		return null;
	},
	updateState:function(str){
		var s = JSON.parse(str);
		//console.log(s.cn);
		var smap = this.data[s.cn];
		if(!smap){
			smap = {};
			this.data[s.cn]=smap;
		}
		if(this.logpr[s.pr]){
			console.log(s);
		}
		//console.log(s.cn+"--"+s.key)
		switch(s.action){
		case 'A':
			smap[s.key]=s;
			break;
		case 'R':
			delete smap[s.key];
			break;
		case 'U':
			for(x in s){
				smap[s.key][x]=s[x];
			}
			break;
		}
		var func =this.func_state[s.cn];
		if(func){
			func(s);
		}
	},
	onmessage:function(evt){
		this.updateState(evt.data);
		this.evt_func("onmessage");
	},
	onclose:function(){
		this.data = {};
		this.evt_func("onclose");
	},
	evt_func:function(evt){
		var func = this.func_evt[evt];
		if(func){
			func();
		}
	},
	onopen:function(){
		this.data = {};
		//如果存在订阅类,重新发送之
		if(this.scns && this.scns.length>0){
			this.send_subscribe(this.scns,'A',this.cn_ids,this.fids);
		}
		this.evt_func("onopen");
	},
	send:function(data){
		this.ws.send(data);	
	},
  	send_subscribe:function(cns,action,cn_ids,fids){
	 var sc = {"cn":"SC_SUBSCRIBE","items":{"map":{"prs":cns,"cns":cn_ids,"fids":fids}
	 ,"javaClass":"java.util.HashMap"},"action":action
	 ,"javaClass":"net.sk.pt.State","key":null};
	 this.send(JSON.stringify(sc));
	 //初次订阅
	 var ss =[];
	 var scns = this.scns||[];
	 if(action=='R'){
		 for(var i=0; i<scns.length; i++){
		 	var cn = scns[i];
	 		var bR = false;
	 		for(var j=0;j<cns.length; j++){
	 			if(cn==cns[j]){
	 				bR = true;
	 				break;
	 			}
	 		}
	 		//无需删除
	 		if(!bR){
	 			ss[ss.length]=cn;
	 		}
		 }
		 this.scns=ss;
	 }else{
	 	for(var i=0; i<cns.length; i++){
	 		var bA = true;
	 		var cn= cns[i];
	 		for(var j=0; j<scns.length; j++){
	 			if(scns[j]==cn){
	 				bA = false;
	 				break;
	 			}
	 		}
	 		//需增加
	 		if(bA){
	 			ss[ss.length]=cn;
	 		}
	 	}
	 	this.scns = scns.concat(ss);
	 }
	 
  	},
	connect:function(){
		var WSocket = window.WebSocket||window.MozWebSocket;
		if (!WSocket) 
			return;
		// 创建WebSocket
		var ws = new WSocket(this.url);
		var self = this;
		// 收到消息时在消息框内显示
		ws.onmessage = function(evt){
			self.onmessage(evt);
		}
		// 断开时会走这个方法
		ws.onclose = function(){
			self.onclose();
			if(self.con_span>0){
				setTimeout(function(){
					self.connect();
				},self.con_span);
			}
		}
		// 连接上时走这个方法
		ws.onopen = function(){
			self.onopen();
		}
		this.ws = ws;
	}
});

